package team.southcat.wsyygh.user.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import team.southcat.wsyygh.common.exception.WsyyghException;
import team.southcat.wsyygh.common.result.ResultCodeEnum;
import team.southcat.wsyygh.common.util.JwtUtil;
import team.southcat.wsyygh.model.enums.AuthStatusEnum;
import team.southcat.wsyygh.model.pojo.user.LoginVo;
import team.southcat.wsyygh.model.pojo.user.PatientVo;
import team.southcat.wsyygh.model.pojo.user.User;
import team.southcat.wsyygh.model.pojo.user.UserVo;
import team.southcat.wsyygh.user.mapper.UserMapper;
import team.southcat.wsyygh.user.service.PatientService;
import team.southcat.wsyygh.user.service.UserService;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private PatientService patientService;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public Page getUserPageList(int page, int limit, User user) {
        Page<User> pageInfo = new Page<>(page, limit);

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(user.getUserName() != null, User::getUserName, user.getUserName());
        queryWrapper.eq(user.getAuthStatus() != null, User::getAuthStatus, user.getAuthStatus());
        queryWrapper.orderByDesc(User::getUpdateTime);

        Page<User> userPage = baseMapper.selectPage(pageInfo, queryWrapper);
        Page<UserVo> result = new Page<>();
        BeanUtils.copyProperties(userPage, result);

        List<User> records = userPage.getRecords();
        List<UserVo> userVos = records.stream().map(item -> {
            return swithVo(item);
        }).collect(Collectors.toList());

        result.setRecords(userVos);

        return result;
    }

    //获取用户信息，包括就诊人信息
    @Override
    public UserVo getDetail(long id) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, id);
        User user = baseMapper.selectOne(queryWrapper);
        UserVo userVo = swithVo(user);
        return userVo;
    }

    //用户（手机号）/(微信+绑定手机号）登录
    @Override
    public Map<String, Object> loginUser(LoginVo loginVo) {
        //从loginVo获取输入的手机号和验证码，并判断是否为空
        String phone = loginVo.getPhone();
        String code = loginVo.getCode();
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            throw new WsyyghException(ResultCodeEnum.PARAM_ERROR);
        }

        //判断手机验证码和输入验证码是否一致
        String redisCode = redisTemplate.opsForValue().get(phone);
        if(!code.equals(redisCode)){
            throw new WsyyghException(ResultCodeEnum.CODE_ERROR);
        }

        //如果登录信息包括openid，说明需要绑定手机号码
        User user = null;
        if (!StringUtils.isEmpty(loginVo.getOpenid())){
            user = this.selectWxInfoOpenId(loginVo.getOpenid());
            if (user != null){
                user.setPhone(loginVo.getPhone());
                this.updateById(user);
            }else{
                throw new WsyyghException(ResultCodeEnum.DATA_ERROR);
            }
        }

        //如果没进行手机号码绑定，正常进行手机号登录
        if (user == null){
            //判断该手机号是否为第一次登录
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getPhone, phone);
            user = baseMapper.selectOne(queryWrapper);

            if (user == null){
                //注册
                user.setNickName("");
                user.setPhone(phone);
                user.setStatus(1);
                baseMapper.insert(user);
            }
        }

        //判断是否被禁用
        if (user.getStatus() == 0){
            throw new WsyyghException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
        }

        //登录成功

        //返回页面显示名称
        Map<String, Object> map = new HashMap<>();
        String name = user.getUserName();
        if(StringUtils.isEmpty(name)){
            name = user.getNickName();
        }
        if(StringUtils.isEmpty(name)){
            name = user.getPhone();
        }
        map.put("name", name);
        String token = JwtUtil.sign(name, String.valueOf(user.getId()));
        map.put("token", token);
        return map;
    }

    @Override
    public User selectWxInfoOpenId(String openid) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getOpenid, openid);
        User user = baseMapper.selectOne(queryWrapper);
        return user;
    }

    @Override
    public void userAuth(User user) {
        Long id = user.getId();
        User selectUser = baseMapper.selectById(id);
        selectUser.setUserName(user.getUserName());
        selectUser.setCertificatesType(user.getCertificatesType());
        selectUser.setCertificatesNo(user.getCertificatesNo());
        selectUser.setCertificatesUrl(user.getCertificatesUrl());
        selectUser.setAuthStatus(AuthStatusEnum.AUTH_RUN.getStatus());

        //更新
        baseMapper.updateById(selectUser);
    }

    @Override
    public UserVo selectById(String userId) {
        User user = baseMapper.selectById(userId);
        UserVo userVo = this.swithVo(user);
        return userVo;
    }


    private UserVo swithVo(User item) {
        UserVo userVo = new UserVo();
        if (item != null){
            BeanUtils.copyProperties(item, userVo);
        }

        //设置另外的数值
        //状态
        userVo.setStatusString(item.getStatus() == 0 ? "锁定" : "正常");
        //认证状态
        userVo.setAuthStatusString(AuthStatusEnum.getStatusNameByStatus(item.getAuthStatus()));
        //就诊人
        List<PatientVo> patientVos = patientService.getByUserId(item.getId());
        userVo.setPatients(patientVos);

        return userVo;
    }
}
